package service;

import android.app.DownloadManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.ArrayMap;
import android.widget.Toast;

import com.socks.library.KLog;
import com.sxpjyy.monkey.mobilenurse.R;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.Objects;

import mytools.ApplicationUtil;
import mytools.CurrentVersion;
import mytools.DateUtil;
import mytools.FileUtil;
import mytools.MyServiceUtil;
import mytools.NetWorkUtil;
import mytools.UpdateInfo;
import retrofit2.Call;
import retrofit2.Callback;


public class UpdateService extends Service {

    private boolean isThreadRunning = false;
    private boolean isCheckingUpdate = true;

    private int newVerCode;
    private String newVerName;
    private ToServiceReceiver toServiceReceiver = null;

    private Call<String> systemTimeCall;

    private String ServerPath = null;

    private long downLoadApkID;

    private UpdateThread updateThread;

    private ApplicationUtil myApplication;
    private DownloadManager downloadManager;

    @Override
    public IBinder onBind(Intent intent) {

        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        myApplication = (ApplicationUtil) getApplication();
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ApplicationUtil.applicationContext);
        //服务器地址
        ServerPath = sharedPreferences.getString("serverAddress", UpdateService.this.getResources().getString(R
                .string.default_server));

        toServiceReceiver = new ToServiceReceiver();
        IntentFilter intentFilter = new IntentFilter("toUpdateService");
        registerReceiver(toServiceReceiver, intentFilter);

    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (updateThread == null) {
            updateThread = new UpdateThread();
        }
        if (!updateThread.isAlive()) {
            isThreadRunning = true;
            isCheckingUpdate = true;
            updateThread.start();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopUpdateThread();
        unregisterReceiver(toServiceReceiver);
        if (systemTimeCall != null && systemTimeCall.isExecuted()) {
            systemTimeCall.cancel();
        }
    }

    private void stopUpdateThread() {
        if (updateThread != null && updateThread.isAlive()) {
            isThreadRunning = false;
            isCheckingUpdate = false;
            updateThread.interrupt();
            updateThread = null;
        }
    }

    //更新线程
    private class UpdateThread extends Thread {
        @Override
        public void run() {
            super.run();
            int result;
            while (isThreadRunning) {
                if (isCheckingUpdate) {//检查更新
                    isCheckingUpdate = false;
                    Intent intent = new Intent("updatebroadcast");
                    if (isNetWorkAvailable()) {//网络连接是否可用
                        collectDeviceInfo();
                        if (getServerVersionCode()) {//获取服务器版本
                            int currentCode = CurrentVersion.getVerCode(UpdateService.this);//本地应用版本
                            if (newVerCode > currentCode) {
                                intent.putExtra("newVerCode", newVerCode);
                                intent.putExtra("newVerName", newVerName);
                                result = 0x12;
                            } else {
                                result = 0x11;
                            }
                            intent.putExtra("updatecode", result);//更新代码,0x11：无更新，0x12：有更新
                        } else {
                            intent.putExtra("updatecode", 0x18);//0x18无法连接到服务器
//                            Thread.interrupted();
                        }
                    } else {
                        intent.putExtra("updatecode", 0x17);//0x17网络无连接
                    }

                    isThreadRunning = false;
                    sendBroadcast(intent);
                    stopUpdateThread();
                }
                SystemClock.sleep(5000);
            }
        }
    }

    /**
     * 收集设备参数信息
     */
    private void collectDeviceInfo() {
        ArrayMap<String, String> DEVICE_INFO = myApplication.getDeviceInfos();
        NetWorkUtil.getNetInfo();
        String IPV4_ADD = NetWorkUtil.IPV4_ADD;
        String MAC_ADD = NetWorkUtil.MAC_ADD;
        DEVICE_INFO.put("Ipv4Address", IPV4_ADD);
        DEVICE_INFO.put("MacAddress", MAC_ADD);
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                DEVICE_INFO.put(field.getName(), field.get(null).toString());
            } catch (Exception e) {
                KLog.d(e.getMessage());
            }
        }
        myApplication.setDeviceInfos(DEVICE_INFO);
    }


    //判断网络是否可用
    private boolean isNetWorkAvailable() {
        ConnectivityManager conn = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = conn != null ? conn.getActiveNetworkInfo() : null;
        return networkInfo != null && networkInfo.isAvailable();
    }

    //获取服务器版本号
    private boolean getServerVersionCode() {

        try {
            String newVerJSON = UpdateInfo.getUpdateVerJSON(UpdateService.this);
            if (!(newVerJSON == null || newVerJSON.equals("") || newVerJSON.startsWith("<!DOCTYPE html>"))) {

                JSONArray jsonArray = new JSONArray(newVerJSON);
                if (jsonArray.length() > 0) {
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject object = jsonArray.getJSONObject(i);
                        if (object.getString("apkname").equals(getResources().getString(R.string.apk_name))) {
                            newVerCode = Integer.parseInt(object.getString("vercode"));
                            newVerName = object.getString("vername");
                            return true;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    private void doDownLoadFile() {
        //先清空下载目录
        String path = Objects.requireNonNull(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)).getAbsolutePath();
        if (!FileUtil.deleteFile(path)) {
            KLog.d("删除旧文件失败！");
        }
        String apkUrl = "http://" + ServerPath + File.separator + getResources().getString(R.string.apk_name);
        Uri uri = Uri.parse(apkUrl);
        DownloadManager.Request request = new DownloadManager.Request(uri);
        request.setDestinationInExternalFilesDir(getApplicationContext(), Environment.DIRECTORY_DOWNLOADS, getResources().getString(R.string.apk_name));
        request.setMimeType("application/vnd.android.package-archive");
        downLoadApkID = downloadManager.enqueue(request);
    }

    private void installByID() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Uri fileUri = null;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            fileUri = downloadManager.getUriForDownloadedFile(downLoadApkID);
        } else {
            File apkFile = queryDownloadedApk();
            if (apkFile.exists()) {
                fileUri = Uri.fromFile(apkFile);
            }
        }
        if (fileUri != null) {
            intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }

    private File queryDownloadedApk() {
        File targetApkFile = null;
        if (downLoadApkID != -1) {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downLoadApkID);
            query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
            Cursor cur = downloadManager.query(query);
            if (cur != null) {
                if (cur.moveToFirst()) {
                    String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

                    targetApkFile = new File(Objects.requireNonNull(Uri.parse(uriString).getPath()));
                }
                cur.close();
            }
        }
        return targetApkFile;
    }

    private class ToServiceReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int code = intent.getIntExtra("toservice", -1);
            switch (code) {
                case -1:
                    break;
                case 0x11://确认更新
                    doDownLoadFile();
                    break;
                case 0x12://更新检查
                    isCheckingUpdate = true;
                    break;
                case 0x13:
                    installByID();
                    break;
            }
        }
    }

    //获取服务器时间
    private void doGetServerTime() {
        systemTimeCall = MyServiceUtil.getSystemTimeCall();
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, retrofit2.Response<String> response) {
                String result = response.body();
                if (result != null) {
                    result = result.replace("\"", "");
                    Date serverDate = DateUtil.getDTFormatDateTime(result);
                    if (serverDate != null) {
                        long delta = serverDate.getTime() - new Date(System.currentTimeMillis()).getTime();
                        myApplication.setDeltaTime(delta);
                        Toast.makeText(getApplicationContext(), "同步服务器时间成功！", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Toast.makeText(getApplicationContext(), "获取服务器时间出错:" + t.toString(), Toast.LENGTH_SHORT).show();
            }
        };
        systemTimeCall.enqueue(callback);
    }
}
